<template>
	<section>
		<!--工具条-->
    <!--
    :inline="true" - 显示在一行
      v-model="keyword" - 双向绑定模型数据
      placeholder="请输入关键字查询" - 框内阴影显示
      v-on:click="keywordQuery" - 点击查询按钮绑定单击事件调用方法keywordQuery
    -->
		<el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
			<el-form :inline="true">
				<el-form-item>
					<el-input v-model="keyword" placeholder="请输入关键字查询"></el-input>
				</el-form-item>
				<el-form-item>
					<el-button type="primary" v-on:click="keywordQuery" icon="el-icon-search" v-perm="'department:list'">查询</el-button>
				</el-form-item>
				<el-form-item>
					<el-button type="primary" @click="handleAdd" icon="el-icon-plus" v-perm="'department:save'">新增</el-button>
				</el-form-item>
			</el-form>
		</el-col>

		<!--列表-->
    <!--
      el-table - elementUI提供的表格框架
      :data="departments" - 绑定模型数据departments
      highlight-current-row -当鼠标移入到某行的时候，行会比其他行亮一些，体验感好
      v-loading="listLoading" - elementUi提供的组件：加载框；true为显示加载框，false为关闭加载框
      @selection-change="selsChange" - @selection-change事件：批量删除选择数据改变的时候绑定一个selsChange方法
      style="width: 100%;" - 表格占屏幕的宽比
    -->
		<el-table :data="departments" highlight-current-row v-loading="listLoading"
              @selection-change="selsChange" style="width: 100%;">
			<el-table-column type="selection" width="55">
			</el-table-column>
			<el-table-column type="index" label="序号" width="60">
			</el-table-column>
			<el-table-column prop="sn" label="部门编号" width="150" sortable>
			</el-table-column>
			<el-table-column prop="name" label="部门名字" width="150" sortable>
			</el-table-column>
			<el-table-column prop="dirPath" label="上级层级" width="150" sortable>
			</el-table-column>
			<el-table-column prop="state" label="部门状态" width="150" sortable>
        <template slot-scope="scope">
          <span style="color: green" v-if="scope.row.state==1">正常</span>
          <span style="color: red" v-else-if="scope.row.state==0">停用</span>
          <span style="color: darkslategray" v-else>未知</span>
        </template>
			</el-table-column>
			<el-table-column prop="manager.username" label="部门经理" width="150" sortable>
			</el-table-column>
      <el-table-column prop="parent.name" label="上级部门" width="150" sortable>
			</el-table-column>
      <!--
        scope="scope" - 这个属性值可以获取当前行对象的信息
        @click="handleEdit(scope.$index, scope.row)"
          @click="handleEdit() - 点击按钮绑定单击事件，调用handleEdit()方法
          scope.$index - 表格的列下标
          scope.row - 当前行的对象
      -->
			<el-table-column label="操作" width="200">
				<template scope="scope">
					<el-button type="success" size="small" round icon="el-icon-edit-outline"
                     @click="handleEdit(scope.$index, scope.row)" v-perm="'department:save'">编辑</el-button>
					<el-button type="danger" round icon="el-icon-delete" size="small"
                     @click="handleDel(scope.$index, scope.row)" v-perm="'department:delete'">删除</el-button>
				</template>
			</el-table-column>
		</el-table>

		<!--工具条：批量删除 + 分页栏-->
    <!--
      @current-change="handleCurrentChange" - 分页栏当前页一改变就调用handleCurrentChange方法
      :page-size="pageSize" - 每页的条数
      :total="totals" - 总数量
      :current-page="currentPage" - 当前页
      :disabled="this.sels.length===0" - 判断如果集合里面的对象为0，就禁止操作
    -->
		<el-col :span="24" class="toolbar">
			<el-button type="danger" @click="batchRemove" :disabled="this.sels.length===0" v-perm="'department:patchDelete'">批量删除</el-button>
			<el-pagination layout="prev, pager, next" @current-change="handleCurrentChange"
                     :page-size="pageSize" :total="totals" :current-page="currentPage" style="float:right;">
			</el-pagination>
		</el-col>

    <!-- 添加或修改的对话框
    el-dialog - elementUi提供的对话框 = 模态框
      :title="title" - 动态改变标题
      :visible.sync="saveFormVisible"  - 模态框的显示状态
      :close-on-click-modal="false" - 关闭模态框只能通过模态框的x关闭，点击空白处不能关闭模态框
    el-form - 表单
      :model="saveForm" - 绑定表单对象
      label-width="80px" - 标签宽度
      :rules="saveFormRules" - 验证规则
      ref="saveForm" - 为当前模态框取名
      prop="name" - 如果当前字段要验证，就必须写，出现*
      auto-complete="off" - 不自动提示
    -->
    <el-dialog :title="title" :visible.sync="saveFormVisible" :close-on-click-modal="false">
      <el-form :model="saveForm" label-width="80px" :rules="saveFormRules" ref="saveForm">
        <el-form-item label="编号" prop="sn">
          <el-input v-model="saveForm.sn" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="saveForm.name" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="saveForm.state">
            <el-radio class="radio" :label="1">启用</el-radio>
            <el-radio class="radio" :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="部门经理">
          <!-- 经理对话框回显
              clearable - 可以清空框内数据
              el-select - elementUI提供的选择器
              v-model="saveForm.manager_id" - 双向绑定：获取点击的对象的部门经理的id
              placeholder="请选择部门经理" - 提示语

              el-option - 每一个选项
              v-for="item in managers" - 遍历
              :label="item.username" - 回显的数据
              :value="item.id" - 向后端传递的数据
              style="float: left">{{ item.username }} - 下拉之后左边显示的数据
              style="float: right; color: #8492a6; font-size: 13px">{{ item.phone }} - 下拉之后右边显示的数据
          -->
          <el-select v-model="saveForm.manager_id"  placeholder="请选择部门经理" clearable>
            <el-option v-for="item in managers"
                :label="item.username"
                :value="item.id"
            >
              <span style="float: left">{{ item.username }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.phone }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <!--
          el-cascader - elementUI提供的无限级树
          :options="deptTree" - 数据来源自模型数据deptTree

          v-model="saveForm.parent"
          clearable - 可以清空框内数据
         -->
        <el-form-item label="上级部门">
          <el-cascader v-model="saveForm.parent" placeholder="请选择部门"
              :options="deptTree"
              :props="{ checkStrictly: true,
                label: 'name', // 级联框显示那个属性的值
                value: 'id'    // 回显时需要,回传值的时候也需要
              }"
              clearable>
          </el-cascader>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click.native="saveFormVisible = false">取消</el-button>
        <el-button type="primary" @click.native="saveSubmit" :loading="saveLoading">提交	</el-button>
      </div>
    </el-dialog>

	</section>
</template>

<script>
	export default {
		data() {
			return {
			  //分页查询的模型数据
        departments: [], //绑定数据到表格 - 显示列表数据 - 请求完成之后
        totals: 1, //数据总数量 - 计算分页栏 - 请求完成之后
        currentPage: 1, //当前页
        pageSize: 5, //每页显示的条数
        listLoading: false, //加载框


        //关键字查询模型数据
        keyword: "",


        //批量删除的模型数据
        sels: [],//列表选中列 - 装的是选中的对象集合


        //添加或修改
				saveFormVisible: false, //对话框是否显示
        saveLoading: false, //对话框中的加载框
        title: '', //对话框名
        saveFormRules: { //校验
					sn: [
            //如果sn失去焦点，框里的内容为空就会显示红色的请输入部门编号的提示
						{ required: true, message: '请输入部门编号', trigger: 'blur' }
					],
          //如果name失去焦点，框里的内容为空就会显示红色的请输入部门编号的提示
          name: [
            { required: true, message: '请输入部门名称', trigger: 'blur' }
          ]
				},

				//对话框数据
        saveForm: {
					id: null,
          sn: '',
					name: '',
          state: 1,
          manager_id: null,
          parent_id: null,
          manager: null,
          parent : null
				},


        //部门经理们
        managers: [],

        //部门树
        deptTree: []
			}
		},
		methods: {
      //1.获取部门列表：分页查询
      getDepartments() { //封装axios发送异步请求的方法
        let para = {
          currentPage: this.currentPage, //当前页
          pageSize: this.pageSize, //每页显示的条数
          keyword: this.keyword //高级查询：关键字
        };
        this.listLoading = true; //显示加载框
        //NProgress.start();
        this.$http.post("/department", para).then(res => { //成功
          this.totals = res.data.totals; //将后端回调函数的totals赋值给模型数据totals【后端返回的数据有总数量和当前页的数据】
          this.departments = res.data.data; //将后端回调函数的data赋值给模型数据departments【后端返回的数据有总数量和当前页的数据】
          this.listLoading = false; //关闭加载框
          //NProgress.done();
        }).catch(res => { //失败
          this.$message.error('系统繁忙，请稍后重试！');
        });
      },

      //2.点击某一页触发的方法
      handleCurrentChange(val) { //val是当分页栏页面发生变化的时候会返回一个当前页面的页数，这里用参数接收
        this.currentPage = val; //将参数val赋值给模型数据
        this.getDepartments(); //重新获取当前页的数据【当分页栏分生变化数据也要变】
      },


      //3.关键字查询绑定的单击事件方法
      keywordQuery() {
        this.currentPage = 1; //查询出来的数据从第一页开始显示
        this.getDepartments(); //刷新数据
      },


      //4.删除
      handleDel: function (index, row) {

        this.$confirm('确认删除该记录吗?', '温馨提示', { //弹出提示框
          type: 'warning'
        }).then(() => {
          this.listLoading = true; //显示加载框
          //获取id
          var id = row.id;
          this.$http.delete("/department/" + id).then(res => { //向后端发起删除请求并携带参数
            //res回调函数：后端传过来的数据
            if (res.data.success) { //如果后端传过来的AjaxResult的success为true：表示删除成功
              this.$message.success('删除成功！'); //消息提示框：3s后消失，没有叉掉的选项


              //计算总页数：向上取整
              var totalPage = Math.ceil(this.totals/this.pageSize); //总数量除以每页显示的条数：例子：25/4：向上取整为7页
              // 假如当前页是最后一页 在最后一页删除数据
              // 并且当前页不是第一页
              // 并且总数量-1模当前页的显示的条数等于0 ：
              // 【假如现在总数量为26；第6页是最后一条了，删除后，就是25/5就等于0，就需要跳转到上一页】
              if (totalPage == this.currentPage && this.currentPage > 1 && (this.totals-1)%this.pageSize == 0) {
                this.currentPage = this.currentPage - 1;
              }

              this.getDepartments(); //删除成功：刷新页面
            }else {
              this.$message.error('系统繁忙，请稍后重试！[500]'); //消息提示框：3s后消失，没有叉掉的选项
            }
            this.listLoading = false; //关闭加载框
          }).catch(res => { //删除失败

            this.$message.error('系统繁忙，请稍后重试！[400、404]'); //消息提示框：3s后消失，没有叉掉的选项
          })
        }).catch(() => { //点击取消

        });
      },


      //5.批量删除选择改变的时候
      selsChange: function (sels) {
        this.sels = sels; //选中多少对象集合就有多少
      },
      //6.批量删除
      batchRemove: function () {
        var ids = this.sels.map(item => item.id); //获取集合对象中的所有id值，是一个集合
        this.$confirm('确认删除选中记录吗？', '提示', {
          type: 'warning'
        }).then(() => {
          this.listLoading = true;
          this.$http.patch("/department", ids).then(res => {
            if (res.data.success) {
              this.currentPage = 1; //删除之后跳转到第一页
              this.$message.success('删除成功！'); //消息提示框：3s后消失，没有叉掉的选项
              this.getDepartments(); //删除成功：刷新页面
            }else {
              this.$message.error('系统繁忙，请稍后重试！[500]'); //消息提示框：3s后消失，没有叉掉的选项
            }
            this.listLoading = false; //关闭加载框
          }).catch(res => {
            this.$message.error('系统繁忙，请稍后重试！[400、404]'); //消息提示框：3s后消失，没有叉掉的选项
          })
        }).catch(() => { //点击取消

        });
      },


      //7.点击修改显示对话框
      handleEdit: function (index, row) {
        //设置对话框的名
        this.title = " 修 改 ";
        //将数据row复制给空集合，修改的时候就不是直接修改数据：不会影响模型数据的值
        this.saveForm = Object.assign({}, row); //row：当前行对象

        //点击修改就发起请求获取所有经理对象
        this.getManagers();
        //点击修改就发起请求获取部门树
        this.getDeptTree();

        //获取当前行对象的dirPath值
        var dirPath = row.dirPath; //字符串  例：部门10，dirPath为/2/5/10
        var dirPathArr = dirPath.split("/"); //拆分后为数组格式，数组里面的元素为字符串 部门10拆分后为["","2","5","10"]
        var arr = [];
        for (var i = 1; i < dirPathArr.length - 1; i++) { //循环遍历，我们只需要拿到他的上级部门数组,格式为整数，不是字符串  [2,5]
          arr[i-1] = parseInt(dirPathArr[i]); //将遍历出来的字符串转成整数添加到arr数组里【arr数组从下标0开始】
        }
        this.saveForm.parent = arr; //例子部门10 [2,5]
        //弹出对话框：先加载数据再弹出对话框
        this.saveFormVisible = true;
      },


			//8.点击添加显示对话框
			handleAdd: function () {
        //设置对话框的名
        this.title = " 添 加 ";
        //清空界面数据：恢复默认
				this.saveForm = {
          id: null,
          sn: '',
          name: '',
          state: 1,
          manager_id: null,
          parent_id: null,
          manager: null,
          parent : null
				};

        //点击添加就发起请求获取所有经理对象
        this.getManagers();
        //点击修改就发起请求获取部门树
        this.getDeptTree();
        //弹出对话框：先加载数据再弹出对话框
        this.saveFormVisible = true;
			},
			//9.添加及修改
			saveSubmit: function () {
				this.$refs.saveForm.validate((valid) => { //检验表单必填项是否都有值，如果有没有值的就不能提交
					if (valid) {
						this.$confirm('确认提交吗？', '提示', {}).then(() => {
							this.saveLoading = true;
              let paras = Object.assign({}, this.saveForm); //将表单的数据赋值给对象paras

              //对父部门进行处理
              var parentTemp = paras.parent; //获取数组  例子部门10 [2,5]
              if (parentTemp) { //如果有上级部门
                paras.parent = null; //给父对象赋值为null，避免400错误：这里向后端传递是数组，而后端是对象，报错
                //数组最后一个值才是当前部门的父部门id
                paras.parent_id = parentTemp[parentTemp.length-1];
              }



							this.$http.put("/department", paras).then(res => {
							  if (res.data.success) {
                  this.$message.success('操作成功！'); //消息提示框：3s后消失，没有叉掉的选项
                  this.getDepartments(); //操作成功：刷新页面
                }else {
                  this.$message.error('系统繁忙，请稍后重试！[500]'); //消息提示框：3s后消失，没有叉掉的选项
                }
							  //关闭加载框
                this.saveLoading = false;
                //关闭对话框
							  this.saveFormVisible = false;
              }).catch(res => {
                this.$message.error('系统繁忙，请稍后重试！[400、404]'); //消息提示框：3s后消失，没有叉掉的选项
              })
						});
					}
				});
			},


      //10.获取部门经理们
      getManagers() {
        this.$http.get("/employee").then(res => { //发请请求向后端获取员工的所有数据
          this.managers = res.data; //将获取到的所有经理对象赋值给模型数据
        }).catch(res => {

        })
      },


      //11.获取部门树
      getDeptTree() {
        this.$http.get("/department/deptTree").then(res => {
          this.deptTree = res.data;
        }).catch(res => {

        })
      }

		},
		mounted() {
			this.getDepartments();
		}
	}

</script>

<style scoped>

</style>